#目的：源自群友想要在.xls的某一行前面插入行。
#方法：先把原.xls文件的每一行都用列表存起来以便调用这些数据。
#注意列表的初始化方式。
#注意用户的行首前插入，内容行内插入，内容行外的插入。
#初版时间：2021-2-9 23:22~2021-2-10 01:49 a.m.
#最终效果最好是能够批量处理文件，再配上些GUI啥的。
#https://www.cnblogs.com/jiangzhaowei/p/5857904.html
#参考网站:https://www.cnpython.com/qa/58694
import xlrd
import xlwt
from xlutils.copy import copy

#第三参数insertLineMaxNumb=1即最大插入行数为1行。
#第二参数insertLine=-1即如传入1则不进行扩行。
def saveWorkSpace(fields,insertLine,insertLineMaxNumb=1):
    '''
    saveWorkSpace(fields,insertLine,insertLineMaxNumb=1)函数功能:
        在.xls的参数2所指定的行插入参数1中的内容，并最终覆盖该.xls。
    传入参数:
        第一参数fields:
            列表，内部元素的内容为插入行的内容。
        第二参数insertLine:
            数字，即需要在哪行插入内容。
        第三参数insertLineMaxNumb:
            数字，默认只插入1行。该参数暂时不起任何作用。
    修改时间:
        2021-2-10 22:35
    '''
    #xlrd
    rb = xlrd.open_workbook('accounts.xls',formatting_info=True)
    r_sheet = rb.sheet_by_index(0)#以index的方式获取sheet，还有以name的方式获取sheet，如.sheet_by_name('...')
    print('r_sheet',r_sheet)
    r = r_sheet.nrows #获取原.xls文件的总行数
    c= r_sheet.ncols#获取原.xls文件的总列数
    print('.xls的总行数为r=',r)
    print('.xls的总列数为c=',c)
    #开始将原.xls文件的每一行写入二维列表中，因为貌似字典很难被循环(可能是我还不会)，故先用列表解决。
    
    #content_mirror_r=[0]*c 使用这种方式初始化列表会导致列表里的东西指向同一个地址，故此处使用for来进行初始化。
    #初始化单层列表元素
    content_mirror_r=[0]
    for q in range(1,c):
        content_mirror_r.append(q)
    print('content_mirror_r',content_mirror_r)
    #content_List=[content_mirror_r]*(r+insertLineMaxNumb)这种*方式生成的列表会导致元素均指向同一个地址。
    #初始化多层列表元素，需要使用pop来终结多余的东西
    #更多方法见    3初始化列表的方法(避免指向同一个元素地址).py
    miniackage_Num=len(content_mirror_r)
    content_List=[[0]]
    for w in range(0,r):
        content_List.append([w])#先初始化外层的[...]列表。
        for e in range(1,miniackage_Num):
            content_List[w].append(e)
    print('未使用pop的content_List=',content_List)
    content_List.pop()
    print('content_List=',content_List)
    '''
    以上如果已知内部miniackage_Num大小很小的话，比如就3个元素，就直接用下面这种方法来初始化：
    content_List=[[0,0,0]]
    for w in range(1,r+1):
        content_List.append([w,w,w])
    '''    
    #读取原.xls中的数据
    for i in range(0,r):#行
        for j in range(0,c):#列
            content_List[i][j]=r_sheet.cell_value(i,j)
        #输出原.xls文件的每一行的内容。
        print(f'第{i+1}行为content_mirror_r[i]=',content_List[i])
    print('content_List=',content_List)
    #xlwt
    wb = copy(rb) 
    sheet = wb.get_sheet(0)
    #insertLine终止判断以后再写。
    if insertLine==0:#在行首前插入。
        for g in range(0,c):
            sheet.write(insertLine,g,fields[g])
        for ff in range(0,r):#insertLine所在行之后的行
            for gg in range(0,c):#列
                sheet.write(ff+insertLineMaxNumb,gg,content_List[ff][gg])
                print(f'content_List[{ff}]=',content_List[ff])
    elif insertLine>0 and insertLine<=r:#在内容行中插入。
        for f in range(0,insertLine):#insertLine所在行之前的行
            for g in range(0,c):#列
                sheet.write(f,g,content_List[f][g])
                print(f'content_List[{f}]=',content_List[f])
        for gg in range(0,c):#插入行，insertLine所在行的列操作
            sheet.write(insertLine-1,gg,fields[gg])
            print(f'fields[{gg}]=',fields[gg])
        for fff in range(insertLine,r+insertLineMaxNumb):#即行数加1
            for ggg in range(0,c):
                sheet.write(fff,ggg,content_List[fff-insertLineMaxNumb][ggg]) #注意这里的-1，因为行内容是取自原本的content_List列表的保存值的。
    elif insertLine>r:#在原本无内容的行插入。
        for f in range(0,r):
            for g in range(0,c):
                sheet.write(f,g,content_List[f][g])
        for gg in range(0,c):
            sheet.write(insertLine-1,gg,fields[gg])
        '''
        原本使用字典时的xlwt 在.xls文件最后一行的写值方式
        sheet.write(r,0,fields['name'])
        sheet.write(r,1,fields['phone'])
        sheet.write(r,2,fields['email'])
        '''
    wb.save('accounts.xls')
    print('Wrote accounts.xls')



#以下为程序主入口
'''
#原本打算使用字典的，但貌似不太好使用数字进行字典的遍历。
a={'name':'hanhan','phone':177,'email':'777@qq.com'}
saveWorkSpace(a)
'''
insertText=['hanhan',177,'777@qq.com']#需要插入的内容。
saveWorkSpace(insertText,4)#参数2，即在第几行插入insertText的内容。如写4就是意味着在第4行插入insertText的内容。
#本文件使用之前需要先在本.py文件同目录下创建一个名为accounts.xls的文件。
#注：编写此文档时.xls的行标是从1开始的，但python中习惯使用0开始的。

#.xls的删除和清除数据的结果是不一样的！
#删除导致的结果r和c都会消失。
#清除数据r和c不会消失。
